package cn.modfun.web.core.interceptor;

import java.lang.reflect.Method;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import cn.modfun.web.core.exception.ParameterValidationException;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

import com.jfinal.aop.Interceptor;
import com.jfinal.aop.Invocation;

import cn.modfun.common.lang.Error;
import cn.modfun.common.lang.Result;
import cn.modfun.common.lang.StringUtils;
import cn.modfun.common.web.RequestUtils;
import cn.modfun.web.core.annotation.Parameter;
import cn.modfun.web.core.annotation.Parameter.LengthMode;
import cn.modfun.web.core.annotation.RequestConfig;
import cn.modfun.web.core.annotation.RequestParameter;
import cn.modfun.web.core.exception.ParameterValidationException;

public class ParameterValidatorInterceptor implements Interceptor {

	@Override
	public void intercept(Invocation inv) {
		// TODO Auto-generated method stub
		Method method = inv.getMethod();
		/**
		 * 获得请求方法的请求配置注解
		 */
		RequestConfig requestConfig = method.getAnnotation(RequestConfig.class);
		/**
		 * 获取请求参数
		 */
		RequestParameter requestParameter = method.getAnnotation(RequestParameter.class);
		if(requestParameter!=null){
			/* 设置参数验证 */
			try {
				parameterValidation(inv,requestConfig,requestParameter);
			} catch (ParameterValidationException e) {
				//e.printStackTrace();
				if(RequestUtils.isAjax(inv.getController().getRequest())){
					inv.getController().renderJson(new Result(new Error("parameter-exception",e.getMessage())));
				}else{
					inv.getController().renderText("参数异常："+e.getMessage());
				}
				return;
			}
		}
		inv.invoke();
	}
	/**
	 * 
	 * @param rc
	 * @param rp
	 * @throws Exception 
	 */
	public void parameterValidation(Invocation inv,RequestConfig rc,RequestParameter rp) throws ParameterValidationException{
		for(Parameter parameter : rp.value()){
			String value = inv.getController().getPara(parameter.name());
			parameterValidation(parameter,value);
		}
	}
	
	
	/**
	 * 执行具体的验证
	 * @param parameter
	 * @param value
	 * @throws ParameterValidationException
	 */
	public void parameterValidation(Parameter parameter,String value)throws ParameterValidationException{
		/**
		 * 判断对象是否允许为空
		 */
		if(parameter.required() && (value == null || "".equals(value.toString()))){
			throw new ParameterValidationException("[ "+parameter.text()+" ] 不允许为空");
		}
		/**
		 * 类型匹配验证
		 */
		if(value!=null && !"".equals(value.toString())){
			/* 优先对特殊类型进行格式判断 */
			if(Date.class.equals(parameter.clazz())){
				try{
					DateTimeFormatter dtf = DateTimeFormat.forPattern(parameter.dateFormat());
					DateTime dateTime = dtf.parseDateTime(value);
					if(!dateTime.toString(parameter.dateFormat()).equals(value.toString())){
						throw new ParameterValidationException("[ "+parameter.text()+" ] 日期格式错误（格式为："+parameter.dateFormat()+"）");
					}
				}catch(Exception e){
					throw new ParameterValidationException("[ "+parameter.text()+" ] 日期格式错误（格式为："+parameter.dateFormat()+"）");
				}
			}else if(Float.class.equals(parameter.clazz())){
				try{
					Float.parseFloat(value);
				}catch(Exception e){
					throw new ParameterValidationException("[ "+parameter.text()+" ] 类型不匹配");
				}
			}else if(Double.class.equals(parameter.clazz())){
				try{
					Double.parseDouble(value);
				}catch(Exception e){
					throw new ParameterValidationException("[ "+parameter.text()+" ] 类型不匹配");
				}
			}else if(Integer.class.equals(parameter.clazz())){
				try{
					Integer.parseInt(value);
				}catch(Exception e){
					throw new ParameterValidationException("[ "+parameter.text()+" ] 类型不匹配");
				}
			}else if(Long.class.equals(parameter.clazz())){
				try{
					Long.parseLong(value);
				}catch(Exception e){
					throw new ParameterValidationException("[ "+parameter.text()+" ] 类型不匹配");
				}
			}else{
				String _value = value.toString();
				if(!String.class.equals(parameter.clazz()) && !value.getClass().equals(parameter.clazz())){
					throw new ParameterValidationException("[ "+parameter.text()+" ] 类型不匹配");
				}else{
					/* 判断是否存在长度验证 */
					int length = 0;
					String unit = "字符";
					if(LengthMode.Default.equals(parameter.lengthMode())){
						length = _value.length();
					}else if(LengthMode.Byte.equals(parameter.lengthMode())){
						length = StringUtils.getLength(_value);
						unit = "字节";
					}
					if(parameter.minLength() != -1 && length < parameter.minLength()){
						throw new ParameterValidationException("[ "+parameter.text()+" ] 长度不小于 "+parameter.minLength()+" "+unit);
					}
					if(parameter.maxLength() != -1 && length > parameter.maxLength()){
						throw new ParameterValidationException("[ "+parameter.text()+" ] 长度不大于 "+parameter.maxLength()+" "+unit);
					}
					/* 判断是否存在非法字符 */
					if (parameter.illegalString().length > 0){
						for(String str : parameter.illegalString()){
							if(_value.indexOf(str)!=-1){
								throw new ParameterValidationException("[ "+parameter.text()+" ] 存在非法字符\""+str+"\"");
							}
						}
					}
					/* 正则验证 */
					if("custom".equals(parameter.regex().rule()) && !parameter.regex().expression().equals("")){
						/* 自定义正则 */
						Pattern pattern = Pattern.compile(parameter.regex().expression());
						Matcher matcher = pattern.matcher(_value);
						if (!matcher.matches()){
							throw new ParameterValidationException("[ "+parameter.text()+" ] "+parameter.regex().message());
						}
					}
				}
			}
		}
	}
}
